package com.buanalintas.sandals.pos.sale;

import com.buanalintas.bynga.Action;
import com.buanalintas.bynga.Controller;
import com.buanalintas.bynga.Dictionary;
import com.buanalintas.bynga.Field;
import com.buanalintas.bynga.Logger;
import com.buanalintas.bynga.Page;
import com.buanalintas.bynga.Persistence;
import com.buanalintas.bynga.Sequence;
import com.buanalintas.bynga.Utility;
import com.buanalintas.bynga.formatter.DateFormatter;
import com.buanalintas.bynga.formatter.MoneyFormatter;
import com.buanalintas.sandals.pos.entities.PosMasterItemStock;
import com.buanalintas.sandals.pos.entities.PosMasterStatus;
import com.buanalintas.sandals.pos.entities.PosTransactionItemStock;
import com.buanalintas.sandals.pos.entities.PosTransactionReturShopDetail;
import com.buanalintas.sandals.pos.entities.PosTransactionSale;
import com.buanalintas.sandals.pos.entities.PosTransactionSaleDetail;
import com.buanalintas.sandals.pos.item.Item;
import com.buanalintas.sandals.pos.saledetail.SaleDetail;
import com.buanalintas.sandals.pos.status.Status;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Sale extends Page {

    private Field saleId;
    private Field saleUnitId;
    private Field saleUserId;
    private Field saleNumber;
    private Field saleSalesId;
    private Field saleSubtotal;
    private Field saleDiscountPercent;
    private Field saleDiscountNominal;
    private Field saleTotal;
    private Field saleDate;
    private Field saleTimestamp;

    public Sale() {
        super();
        setTheClass(PosTransactionSale.class);
        setPageDetail(SaleDetail.class);

        saleId = new Field();
        saleId.setName("saleId");
        saleId.setCaption("id");
        saleId.setListProperties("");
        saleId.setInputProperties("");
        getFields().add(saleId);

        saleUnitId = new Field();
        saleUnitId.setName("saleUnitId");
        saleUnitId.setCaption("unit");
        saleUnitId.setListProperties("");
        saleUnitId.setInputProperties("");
        getFields().add(saleUnitId);

        saleUserId = new Field();
        saleUserId.setName("saleUserId");
        saleUserId.setCaption("user ");
        saleUserId.setListProperties("");
        saleUserId.setInputProperties("");
        getFields().add(saleUserId);
        
        saleSalesId = new Field();
        saleSalesId.setName("saleSalesId");
        saleSalesId.setCaption("sales");
        saleSalesId.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        saleSalesId.setInputProperties(" ");
        saleSalesId.setRequired(true);
//        saleSalesId.getSelectorColumns();
        getFields().add(saleSalesId);

        saleNumber = new Field();
        saleNumber.setName("saleNumber");
        saleNumber.setCaption("number");
        saleNumber.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        saleNumber.setInputProperties(" size=\"20\" readonly");
        saleNumber.setRequired(true);
        getFields().add(saleNumber);

        saleSubtotal = new Field();
        saleSubtotal.setName("saleSubtotal");
        saleSubtotal.setCaption("subtotal");
        saleSubtotal.setListProperties(" align=\"right\" width=\"20%\" nowrap");
        saleSubtotal.setInputProperties(" size=\"8\"");
        saleSubtotal.setRequired(true);
        saleSubtotal.setFormater(MoneyFormatter.getInstance());
        getFields().add(saleSubtotal);

        saleDiscountPercent = new Field();
        saleDiscountPercent.setName("saleDiscountPercent");
        saleDiscountPercent.setCaption("discount percent");
        saleDiscountPercent.setListProperties(" align=\"right\" width=\"15%\" nowrap");
        saleDiscountPercent.setInputProperties(" size=\"8\"");
        getFields().add(saleDiscountPercent);

        saleDiscountNominal = new Field();
        saleDiscountNominal.setName("saleDiscountNominal");
        saleDiscountNominal.setCaption("discount nominal");
        saleDiscountNominal.setListProperties(" align=\"right\" width=\"20%\" nowrap");
        saleDiscountNominal.setInputProperties(" size=\"8\"");
        saleDiscountNominal.setFormater(MoneyFormatter.getInstance());
        getFields().add(saleDiscountNominal);

        saleTotal = new Field();
        saleTotal.setName("saleTotal");
        saleTotal.setCaption("total");
        saleTotal.setListProperties(" align=\"right\" width=\"20%\" nowrap");
        saleTotal.setInputProperties(" size=\"8\"");
        saleTotal.setRequired(true);
        saleTotal.setFormater(MoneyFormatter.getInstance());
        getFields().add(saleTotal);

        saleDate = new Field();
        saleDate.setName("saleDate");
        saleDate.setCaption("date");
        saleDate.setListProperties(" align=\"center\" width=\"10%\" nowrap");
        saleDate.setInputProperties(" size=\"8\" readonly");
        saleDate.setDefaultValue(Utility.getTimestamp());
        getFields().add(saleDate);

        saleTimestamp = new Field();
        saleTimestamp.setName("saleTimestamp");
        saleTimestamp.setCaption("timestamp");
        saleTimestamp.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        saleTimestamp.setInputProperties(" size=\"8\" readonly");
        saleTimestamp.setDefaultValue(Utility.getTimestamp());
        getFields().add(saleTimestamp);

        getActions().add(Action.TRANS_ADD);
        getActions().add(Action.TRANS_VIEW);
        
        fillFields();

        getFieldsAdd().clear();
        getFieldsAdd().add(saleDate);
        getFieldsAdd().add(saleNumber);
        getFieldsAdd().add(saleSalesId);
        getFieldsAdd().add(saleDiscountPercent);
        getFieldsAdd().add(saleDiscountNominal);

        getFieldsEdit().clear();
        getFieldsEdit().add(saleNumber);
        getFieldsEdit().add(saleDate);
        getFieldsEdit().add(saleSalesId);
        getFieldsEdit().add(saleDiscountPercent);
        getFieldsEdit().add(saleDiscountNominal);

        getFieldsList().clear();
        getFieldsList().add(saleNumber);
        getFieldsList().add(saleDate);
        getFieldsList().add(saleSalesId);
        getFieldsList().add(saleSubtotal);
        getFieldsList().add(saleDiscountPercent);
        getFieldsList().add(saleDiscountNominal);
        getFieldsList().add(saleTotal);

        getFieldsView().clear();
        getFieldsView().add(saleNumber);
        getFieldsView().add(saleSalesId);
        getFieldsView().add(saleSubtotal);
        getFieldsView().add(saleDiscountPercent);
        getFieldsView().add(saleDiscountNominal);
        getFieldsView().add(saleTotal);
        getFieldsView().add(saleTimestamp);

        setController(new SaleController(this));
        setExportList(getClass().getResourceAsStream("SaleList.jasper"));
        setExport(getClass().getResourceAsStream("Sale.jasper"));
    }

//    @Override
//    public void afterInit(HttpServletRequest req, HttpServletResponse res) {
//        saleTimestamp.setFormater(DateFormatter.getInstanceDate(this));
////        saleSalesId.getSelectorColumns().add(new String[]{"salesName", " Name", "width=\"30%\" nowrap"});
//        saleSalesId.setSelectorCondition("t.salesUnitId.unitId="+getCurrentUnit().getUnitId());
////        getFields().add(saleSalesId);
//    }

    @Override
    public void loadDetail(List datas, String id) {
        try {
            EntityManager em = getEntityManager();
            List<PosTransactionSaleDetail> request = em.createQuery("SELECT t FROM PosTransactionSaleDetail t WHERE t.saleDetailSaleId.saleId='" + id + "'").setHint(Persistence.REFRESH_HINT, true).getResultList();
            datas.clear();
            for (PosTransactionSaleDetail saleDetail : request) {
                PosTransactionSale sale = new PosTransactionSale();
                sale.setSaleDiscountNominal(saleDetail.getSaleDetailDiscountNominal());
                sale.setSaleDiscountPercent(saleDetail.getSaleDetailDiscountPercent());
                datas.add(sale);
            }
        } catch (Exception e) {
            Logger.getInstance().log(e);
        }
    }

    @Override
    public void beforeAdd() {
        saleNumber.setDefaultValue(generate());
    }

    @Override
    public void beforeList() {
        getController().setCondition("t.saleUnitId.unitId=" + getCurrentUnit().getUnitId());
    }

    class SaleController extends Controller {

        public SaleController(Page page) {
            super(page);
            setOrder(saleTimestamp);
            setOrderType("DESC");
        }

        @Override
        public void beforeInsert(Object data, List list) {
            PosTransactionSale sale = (PosTransactionSale) data;
            sale.setSaleNumber(generate());
            sale.setSaleUserId(getCurrentUser());
//            sale.setSaleSalesId(getCurrentUser());
            sale.setSaleUnitId(getCurrentUnit());
            sale.setSaleTimestamp(Utility.getTimestamp());
            
//            for (int i = list.size() - 1; i > 0; i--) {
//                PosTransactionSaleDetail d1 = (PosTransactionSaleDetail) list.get(i);
//                for (int j = 0; j < i; j++) {
//                    PosTransactionSaleDetail d2 = (PosTransactionSaleDetail) list.get(j);
//                    if (d2.getSaleDetailItemId().equals(d1.getSaleDetailItemId())) {
//                        d2.setSaleDetailQuantity(d2.getSaleDetailQuantity()+d1.getSaleDetailQuantity());
//                        list.remove(i);
//                        break;
//                    }
//                }
//            }

            BigDecimal subTotal = BigDecimal.ZERO;
            for (int i = 0; i < list.size(); i++) {
                PosTransactionSaleDetail saleDetail = (PosTransactionSaleDetail) list.get(i);
                subTotal = subTotal.add(saleDetail.getSaleDetailTotal());
            }
            BigDecimal total = subTotal;
            BigDecimal percent = BigDecimal.ZERO;
            try {
                percent = subTotal.multiply(sale.getSaleDiscountPercent().divide(new BigDecimal(100)));
            } catch (Exception e) {
                Logger.getInstance().log(e);
            }
            total = total.subtract(percent);
            try {
                total = total.subtract(sale.getSaleDiscountNominal());
            } catch (Exception e) {
                Logger.getInstance().log(e);
            }
            sale.setSaleSubtotal(subTotal);
            sale.setSaleTotal(total);
        }

        
        
        @Override
        public void afterInsert(Object data, List list) {
            EntityManager em = getEntityManager();
            PosMasterStatus statusGood = Status.getStatusGood(em);
            try {
                em.getTransaction().begin();
                PosTransactionSale sale = (PosTransactionSale) data;
                for (Object detail : list) {
                    PosTransactionSaleDetail saleDetail = (PosTransactionSaleDetail) detail;
                    PosMasterItemStock stock = Item.getStock(em, saleDetail.getSaleDetailItemId(), sale.getSaleUnitId(), statusGood, saleDetail.getSaleDetailItemId().getItemColorId(), saleDetail.getSaleDetailSizeId());
                    PosTransactionItemStock itemStock = new PosTransactionItemStock();
                    itemStock.setItemStockId(Sequence.next(itemStock));
                    itemStock.setItemStockItemId(saleDetail.getSaleDetailItemId());
                    itemStock.setItemStockSizeId(saleDetail.getSaleDetailSizeId());
                    itemStock.setItemStockColorId(saleDetail.getSaleDetailItemId().getItemColorId());
                    itemStock.setItemStockUnitId(sale.getSaleUnitId());
                    itemStock.setItemStockStatusId(statusGood);
                    itemStock.setItemStockType("1");
                    itemStock.setItemStockLast(stock.getItemStockValue());
                    itemStock.setItemStockValue(saleDetail.getSaleDetailQuantity());
                    itemStock.setItemStockCurrent(itemStock.getItemStockLast() - itemStock.getItemStockValue());
                    itemStock.setItemStockUserId(getCurrentUser());
                    itemStock.setItemStockTimestamp(Utility.getTimestamp());
                    em.persist(itemStock);
                    stock.setItemStockValue(itemStock.getItemStockCurrent());
                    if (saleDetail.getSaleDetailQuantity().compareTo(itemStock.getItemStockValue()) > 0) {
                        Utility.throwException(saleDetail.getSaleDetailItemId() + " " + Dictionary.getValue(page, "insufficient stock") + ", " + Dictionary.getValue(page, "current stock: ") + ": " + stock.getItemStockValue() + " " + Dictionary.getValue(page, "will be sent") + ": " + saleDetail.getSaleDetailQuantity());
                    }
                }
                em.getTransaction().commit();
            } catch (Exception e) {
                Logger.getInstance().log(e);
            }
        }
    }

    public String generate() {
        String unitCode = (getCurrentUnit()).getUnitCode();
        Calendar cal = Calendar.getInstance();
        String year = "" + cal.get(Calendar.YEAR);
        String month = Utility.intToRoman(cal.get(Calendar.MONTH) + 1);
        try {
            PosTransactionSale sale = (PosTransactionSale) getEntityManager().createQuery("SELECT t FROM PosTransactionSale t WHERE t.saleNumber LIKE '%/" + unitCode + "/SAL/%/" + year + "' ORDER BY t.saleTimestamp DESC").setHint(Persistence.REFRESH_HINT, true).setFirstResult(0).setMaxResults(1).getSingleResult();
            return Utility.lpad(Integer.parseInt(sale.getSaleNumber().substring(0, 4)) + 1, 4, "0") + "/" + unitCode + "/SAL/" + month + "/" + year;
        } catch (Exception e) {
        }
        return "0001/" + unitCode + "/SAL/" + month + "/" + year;
    }
    
        @Override
    public String addJavascript() {
        String calculate = "<script>function __calculatePrice() {"
                + "var price2 = Number(document.getElementById('saleTotal').value);"
                + "document.getElementById('total').value = price2;"
                + "}";
              
        return calculate;
        }

    @Override
    public void beforeExport() {
        getExportParams().put("title", Dictionary.getValue(this, "Sale"));
    }

    @Override
    public void beforeExportMulti() {
        beforeExport();
    }
}